Implementing Type Systems as Macros